<template>
    <div>
        <el-dialog :draggable="true" :model-value="show" :close-on-click-modal="false" @close="handleClose">
            <div class="header">
                <p class="title">{{ title }}</p>
            </div>

            <div class="main">
                <div class="crop-container">
                    <vue-cropper class="crop" ref="cropper" :autoCrop="option.autoCrop"
                        :autoCropHeight="option.autoCropHeight" :autoCropWidth="option.autoCropWidth"
                        :canMove="option.canMove" :canScale="option.canScale" :centerBox="option.centerBox"
                        :fixed="option.fixed" :fixedBox="option.fixedBox" :fixedNumber="option.fixedNumber"
                        :img="option.img" :info="option.info" :info-true="option.infoTrue" :mode="option.mode"
                        :origin="option.origin" :outputSize="option.outputSize" :outputType="option.outputType"
                        :rounded="true" @realTime="realTime"></vue-cropper>

                    <input id="input" ref="input" type="file" accept="image/png, image/jpeg, image/gif, image/jpg"
                        @change="uploadAvatar($event)" v-show="false">

                    <div class="action-buttons">
                        <el-button :size="'small'" type="primary" @click="handleUploadAvatar">上传图片</el-button>
                        <el-button :size="'small'" type="danger" plain :icon="ZoomIn" @click="changeScale(1)">
                            放大
                        </el-button>
                        <el-button :size="'small'" type="danger" plain :icon="ZoomOut" @click="changeScale(-1)">
                            缩小
                        </el-button>
                        <el-button :size="'small'" type="primary" @click="rotateLeft">左旋转</el-button>
                        <el-button :size="'small'" type="primary" @click="rotateRight">右旋转</el-button>
                        <el-button :size="'small'" type="primary" @click="downloadPreView">下载</el-button>
                        <el-button :size="'small'" type="success" @click="confirmCrop">确认</el-button>
                    </div>
                </div>

                <div class="preview-container">
                    <div class="preview-header">
                        <p class="preview-title">预览</p>
                    </div>
                    <div class="preview-wrapper" :style="getPreviewStyle">
                        <div :style="previews.div">
                            <img :src="previews.url" :style="previews.img" alt="" class="preview-img">
                        </div>
                    </div>
                </div>
            </div>
        </el-dialog>
    </div>
</template>

<script setup>
import 'vue-cropper/dist/index.css'
import { VueCropper } from 'vue-cropper'
import { computed, ref } from 'vue'
import { ElMessage } from 'element-plus'
import { ZoomIn, ZoomOut } from '@element-plus/icons-vue'

const props = defineProps({
    // 标题
    title: {
        type: String,
    },
    // 是否显示
    show: {
        type: Boolean,
        default: false
    },
})

const previews = ref({})
const previewBlob = ref()
const previewBase64 = ref()

const emit = defineEmits(['update:show'])

const handleClose = () => {
  emit('update:show', false) // 通知父组件弹窗已关闭
}

const cropper = ref()
const input = ref()
const option = ref({
    autoCrop: true,
    autoCropHeight: '200px',
    autoCropWidth: '200px',
    canMove: true,
    canScale: true,
    centerBox: true,
    fixed: true,
    fixedBox: true,
    fixedNumber: [1, 1],
    img: null,
    info: false,
    infoTrue: true,
    mode: 'contain',
    origin: false,
    outputSize: 1,
    outputType: 'png',
})

// 实时预览
const realTime = (data) => {
    previews.value = data
}

const downloadPreView = () => {
    let aLink = document.createElement('a')
    aLink.download = 'avatar.png'

    cropper.value.getCropBlob((blob) => {
        aLink.href = window.URL.createObjectURL(blob)
        aLink.click()
    })
}

const uploadAvatar = (event) => {
    let file = event.target.files[0]

    if (!/\.(gif|jpg|jpeg|png|bmp)$/i.test(event.target.value)) {
        ElMessage.error('图片类型必须是.gif、jpeg、jpg、png、bmp中的一种')
        return false
    }

    let fileReader = new FileReader()
    fileReader.onload = (event) => {
        let data
        if (typeof event.target.result === 'object') {
            data = window.URL.createObjectURL(new Blob([event.target.result]))
        } else {
            data = event.target.result
        }
        option.value.img = data
    }

    fileReader.readAsArrayBuffer(file)
}

const handleUploadAvatar = () => {
    input.value.click()
}

const getPreviewStyle = computed(() => {
    return {
        'width': previews.value.w + 'px',
        'height': previews.value.h + 'px',
        'overflow': 'hidden',
    }
})

const rotateLeft = () => {
    cropper.value.rotateLeft()
}

const rotateRight = () => {
    cropper.value.rotateRight()
}

const changeScale = (scaleSize) => {
    cropper.value.changeScale(scaleSize)
}

const getBase64 = () => {
    cropper.value.getCropData((base64) => {
        previewBase64.value = base64
    })
}

const getBlob = () => {
    cropper.value.getCropBlob((blob) => {
        previewBlob.value = blob
    })
}

// 确认裁剪
const confirmCrop = () => {
  cropper.value.getCropBlob((blob) => {
    emit('crop', blob)          // 将裁剪后的 Blob 返回给父组件
    emit('update:show', false)  // 关闭弹窗
  })
}

</script>

<style scoped>
.wrapper {
    padding: 15px;
    max-width: 1000px;
    margin: 0 auto;
    background-color: #fff;
    border-radius: 8px;
    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
}

.header {
    margin-bottom: 15px;
    text-align: center;
}

.title {
    font-size: 24px;
    font-weight: bold;
    color: #303133;
    margin: 0;
}

.main {
    display: flex;
    gap: 20px;
    flex-wrap: wrap;
}

.crop-container {
    flex: 1;
    min-width: 300px;
}

.crop {
    width: 100%;
    height: 350px;
    border: 1px solid #e6e6e6;
    border-radius: 4px;
}

.action-buttons {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 15px;
    justify-content: center;
}

.preview-container {
    flex: 0 0 220px;
    display: flex;
    flex-direction: column;
    align-items: center;
}

.preview-header {
    margin-bottom: 10px;
    text-align: center;
}

.preview-title {
    font-size: 16px;
    font-weight: 500;
    color: #606266;
    margin: 0;
}

.preview-wrapper {
    background-color: #f5f7fa;
    border-radius: 50%;
    padding: 10px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
    display: flex;
    align-items: center;
    justify-content: center;
}

.preview-img {
    border-radius: 50%;
    border: 2px solid #dcdfe6;
}

@media (max-width: 768px) {
    .main {
        flex-direction: column;
    }

    .preview-container {
        flex: none;
        width: 100%;
        margin-top: 20px;
    }

    .action-buttons {
        justify-content: space-around;
    }

    .action-buttons .el-button {
        flex: 1;
        margin: 4px;
    }
}
</style>